#include <bits/stdc++.h>
using namespace std;
int speedList[100005];
int aList[100005];
int startPlace[100005];
int checkPlace[100005];
const double minn = 0.001;
struct info{
    double start;
    double over;
};
info checking[100005];
int carNumber,checkingNumber,roadLength,speedLimit;
int times;
void func();
void process();
int two(double number);
bool cmp(info x,info y){
    return x.over < y.over;
}
int main(){
    cin.tie(0);
    cout.tie(0);
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int T;
    cin >> T;
    for (int k = 0;k < T;k++){
        times = 0;
        memset(speedList,0,sizeof(speedList));
        memset(aList,0,sizeof(aList));
        memset(startPlace,0,sizeof(startPlace));
        memset(checkPlace,0,sizeof(checkPlace));
        memset(checking,0,sizeof(checking));
        cin >> carNumber >> checkingNumber >> roadLength >> speedLimit;
        for (int i = 0;i < carNumber;i++){
            cin >> startPlace[i] >> speedList[i] >> aList[i];
        }
        for (int i = 0;i < checkingNumber;i++){
            cin >> checkPlace[i];
        }
        func();
        process();
    }
    return 0;
}
void func(){
    for (int i = 0;i < carNumber;i++){
        if (speedList[i] > speedLimit){
            checking[times].start = startPlace[i];
            double overr = 0;
            if (aList[i] < 0) overr = (pow(speedList[i],2) - pow(speedLimit,2))/(2 * aList[i] * (-1)) + startPlace[i] - minn;
            else  overr = roadLength;
            if (overr > roadLength)overr = roadLength;
            checking[times].over = overr;
            times++;
            continue;
        }
        else{
            if (aList[i] <= 0){
                continue;
            }
            else{
                double startt = abs((pow(speedLimit,2) - pow(speedList[i],2))/(2 * aList[i])) + startPlace[i] + minn;
                if (startt > roadLength)continue;
                checking[times].start = startt;
                checking[times].over = roadLength;
                times++;
            }
        }
    }
    sort(checking,checking+carNumber+1,cmp);
}
void process(){
    double maxn = -1;
    int ans = 0;
    for (int i = 0;i <= carNumber;i++){
        if (checking[i].start == 0 && checking[i].over == 0)continue;
        if (maxn < checking[i].start){
            int number1 = checkPlace[two(checking[i].over)];
            if (number1 > checking[i].over && two(checking[i].over) > 0)number1 = checkPlace[two(checking[i].over)-1];
            if (number1 > checking[i].over && two(checking[i].over) == 0){
                times--;
                continue;
            }
            if (number1 <= checking[i].over){
                if (number1 >= checking[i].start){
                    ans++;
                    maxn = number1;
                    continue;
                }
                else{
                    times--;
                    continue;
                }
            }

        }
    }
    cout << times << " " << checkingNumber-ans << endl;
}
int two(double number){
    int left = 0;
    int right = checkingNumber;
    int mid;
    while (left <= right && left < checkingNumber){
        mid = (left + right)/2;
        if (checkPlace[mid] == number){
            return mid;
        }
        else if (checkPlace[mid] < number){
            left = mid + 1;
        }
        else{
            right = mid - 1;
        }
    }
    if (left >= checkingNumber)return checkingNumber-1;
    return left;
}
